# 声明：本代码仅供学习和研究目的使用。使用者应遵守以下原则：
# 1. 不得用于任何商业用途。
# 2. 使用时应遵守目标平台的使用条款和robots.txt规则。
# 3. 不得进行大规模爬取或对平台造成运营干扰。
# 4. 应合理控制请求频率，避免给目标平台带来不必要的负担。
# 5. 不得用于任何非法或不当的用途。
#
# 详细许可条款请参阅项目根目录下的LICENSE文件。
# 使用本代码即表示您同意遵守上述原则和LICENSE中的所有条款。


import asyncio
import sys
import os
import json
import glob
from typing import Optional

import cmd_arg
import config
from database import db
from base.base_crawler import AbstractCrawler
from media_platform.bilibili import BilibiliCrawler
from media_platform.douyin import DouYinCrawler
from media_platform.kuaishou import KuaishouCrawler
from media_platform.tieba import TieBaCrawler
from media_platform.weibo import WeiboCrawler
from media_platform.xhs import XiaoHongShuCrawler
from media_platform.zhihu import ZhihuCrawler
# 导入NLP处理器
from nlp.nlp_processor import NLPProcessor, API_KEY, SECRET_KEY


class CrawlerFactory:
    CRAWLERS = {
        "xhs": XiaoHongShuCrawler,
        "dy": DouYinCrawler,
        "ks": KuaishouCrawler,
        "bili": BilibiliCrawler,
        "wb": WeiboCrawler,
        "tieba": TieBaCrawler,
        "zhihu": ZhihuCrawler,
    }

    @staticmethod
    def create_crawler(platform: str) -> AbstractCrawler:
        crawler_class = CrawlerFactory.CRAWLERS.get(platform)
        if not crawler_class:
            raise ValueError(
                "Invalid Media Platform Currently only supported xhs or dy or ks or bili ..."
            )
        return crawler_class()


crawler: Optional[AbstractCrawler] = None


def get_latest_json_file(directory: str) -> str:
    """
    获取目录中最新的JSON文件
    """
    # 获取所有JSON文件
    json_files = glob.glob(os.path.join(directory, '*.json'))
    if not json_files:
        return None
    
    # 按修改时间排序，返回最新的文件
    return max(json_files, key=os.path.getmtime)


def process_with_nlp():
    """
    使用NLPProcessor处理爬取的数据并生成可视化结果
    """
    try:
        # 只对小红书平台的数据进行NLP处理
        if config.PLATFORM != "xhs":
            print(f"NLP处理仅支持小红书平台数据，当前平台: {config.PLATFORM}")
            return
        
        # 获取最新的JSON文件
        json_dir = "d:/redbook/MediaCrawler-1/data/xhs/json"
        latest_json_file = get_latest_json_file(json_dir)
        
        if not latest_json_file:
            print(f"未找到可处理的JSON文件: {json_dir}")
            return
        
        print(f"开始使用NLP处理最新的JSON文件: {latest_json_file}")
        
        # 创建NLP处理器
        processor = NLPProcessor(API_KEY, SECRET_KEY)
        
        # 处理JSON文件
        results = processor.process_json_file(latest_json_file)
        
        if not results:
            print("NLP处理失败，没有生成分析结果")
            return
        
        # 获取分析结果文件路径
        base_name = os.path.basename(latest_json_file)
        name_without_ext = os.path.splitext(base_name)[0]
        analyzed_file_path = f"d:/redbook/MediaCrawler-1/data/xhs/json/{name_without_ext}_analyzed.json"
        
        # 生成可视化数据
        print(f"正在从处理后的文件生成可视化数据: {analyzed_file_path}")
        viz_data = processor.generate_visualization_data(analyzed_file_path)
        
        # 保存可视化数据为JSON，供前端使用
        viz_data_path = "d:/redbook/MediaCrawler-1/docs/static/visualization/sentiment_data.json"
        os.makedirs(os.path.dirname(viz_data_path), exist_ok=True)
        
        with open(viz_data_path, 'w', encoding='utf-8') as f:
            json.dump(viz_data, f, ensure_ascii=False, indent=2)
        
        print(f"可视化数据已保存至: {viz_data_path}")
        print("情感分析和评论观点抽取完成！")
        
    except Exception as e:
        print(f"NLP处理过程中发生错误: {e}")


# persist-1<persist1@126.com>
# 原因：增加 --init_db 功能，用于数据库初始化。
# 副作用：无
# 回滚策略：还原此文件。
async def main():
    # Init crawler
    global crawler

    # parse cmd
    args = await cmd_arg.parse_cmd()

    # init db
    if args.init_db:
        await db.init_db(args.init_db)
        print(f"Database {args.init_db} initialized successfully.")
        return  # Exit the main function cleanly


    crawler = CrawlerFactory.create_crawler(platform=config.PLATFORM)
    await crawler.start()
    
    # 爬虫完成后执行NLP处理
    print("爬虫任务完成，开始执行NLP处理...")
    process_with_nlp()


def cleanup():
    if crawler:
        # asyncio.run(crawler.close())
        pass
    if config.SAVE_DATA_OPTION in ["db", "sqlite"]:
        asyncio.run(db.close())


if __name__ == "__main__":
    try:
        asyncio.get_event_loop().run_until_complete(main())
    finally:
        cleanup()
